// transform-class-to-function.js
const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const t = require('@babel/types');
const generate = require('@babel/generator').default;

const filePath = process.argv[2]; // 运行时传入文件路径
if (!filePath) {
  console.error('❌ 请传入要转换的文件路径，如：node transform-class-to-function.js MyComp.tsx');
  process.exit(1);
}

const ext = path.extname(filePath); // 获取扩展名
const code = fs.readFileSync(filePath, 'utf8');

const ast = parser.parse(code, {
  sourceType: 'module',
  plugins: [
    'jsx',
    'classProperties',
    'decorators-legacy',
    ext === '.ts' || ext === '.tsx' ? 'typescript' : null
  ].filter(Boolean),
});

traverse(ast, {
  ClassDeclaration(path) {
    const node = path.node;

    // 1. 检查是否是 React Class Component
    const isReactComponent =
      (t.isMemberExpression(node.superClass) &&
        node.superClass.object.name === 'React' &&
        node.superClass.property.name === 'Component') ||
      (t.isIdentifier(node.superClass) && node.superClass.name === 'Component');

    if (!isReactComponent) return;

    const componentName = node.id.name;
    let stateInit = null;
    let effectBodies = [];
    let bodyStatements = [];

    // 2. 遍历类方法
    node.body.body.forEach(classBodyItem => {
      if (t.isClassProperty(classBodyItem) && classBodyItem.key.name === 'state') {
        stateInit = classBodyItem.value;
      }

      if (t.isClassMethod(classBodyItem)) {
        const methodName = classBodyItem.key.name;

        if (methodName === 'render') {
          bodyStatements = classBodyItem.body.body;
        }

        if (methodName === 'componentDidMount') {
          effectBodies = effectBodies.concat(classBodyItem.body.body);
        }

        if (methodName === 'componentWillUnmount') {
          // 在 useEffect 中返回 cleanup
          effectBodies.push(
            t.returnStatement(
              t.arrowFunctionExpression([], t.blockStatement(classBodyItem.body.body))
            )
          );
        }
      }
    });

    // 3. 创建 function component
    const funcParams = [t.identifier('props')];
    const funcBody = [];

    // useState
    if (stateInit) {
      if (!ast.program.body.some(stmt =>
        t.isImportDeclaration(stmt) &&
        stmt.source.value === 'react' &&
        stmt.specifiers.some(s => s.imported && s.imported.name === 'useState')
      )) {
        ast.program.body.unshift(
          t.importDeclaration(
            [t.importSpecifier(t.identifier('useState'), t.identifier('useState'))],
            t.stringLiteral('react')
          )
        );
      }
      funcBody.push(
        t.variableDeclaration('const', [
          t.variableDeclarator(
            t.arrayPattern([
              t.identifier('state'),
              t.identifier('setState'),
            ]),
            t.callExpression(t.identifier('useState'), [stateInit])
          )
        ])
      );
    }

    // useEffect
    if (effectBodies.length) {
      if (!ast.program.body.some(stmt =>
        t.isImportDeclaration(stmt) &&
        stmt.source.value === 'react' &&
        stmt.specifiers.some(s => s.imported && s.imported.name === 'useEffect')
      )) {
        ast.program.body.unshift(
          t.importDeclaration(
            [t.importSpecifier(t.identifier('useEffect'), t.identifier('useEffect'))],
            t.stringLiteral('react')
          )
        );
      }
      funcBody.push(
        t.expressionStatement(
          t.callExpression(t.identifier('useEffect'), [
            t.arrowFunctionExpression([], t.blockStatement(effectBodies)),
            t.arrayExpression([])
          ])
        )
      );
    }

    // render 内容
    funcBody.push(...bodyStatements);

    const funcDecl = t.functionDeclaration(
      t.identifier(componentName),
      funcParams,
      t.blockStatement(funcBody)
    );

    // 替换 class 成 function
    path.replaceWith(funcDecl);
  }
});

// 4. 生成代码
const output = generate(ast, { retainLines: true }).code;
fs.writeFileSync(filePath, output, 'utf8');
console.log(`✅ 已转换并覆盖原文件：${filePath}`);
